﻿using AppEszköz.Xml;
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace AppEszköz.Trace
{
    public class XmlTraceListener : TraceListener
    {
        private XmlFileWriter xmlWriter;

        public XmlTraceListener()
          : this("trace.xml")
        {
        }

        public XmlTraceListener(string fileName)
        {
            this.xmlWriter = new XmlFileWriter(fileName, "Trace") {MaxFileLength = 1000};
        }

        public override void Write(string message)
        {
            this.Write(message, "NA");
        }

        public override void Write(string message, string category)
        {
            if (new TraceSwitch("TraceLevelSwitch", "Trace Level for Entire Application").Level <= TraceLevel.Off)
                return;
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("<TraceEntry>");
            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append(this.getPreambleMessage());
            stringBuilder.Append("\t<Message>");
            stringBuilder.Append(message);
            stringBuilder.Append("</Message>");
            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append("\t<Category>");
            stringBuilder.Append(category);
            stringBuilder.Append("</Category>");
            stringBuilder.Append(Environment.NewLine);
            stringBuilder.Append("</TraceEntry>");
            stringBuilder.Append(Environment.NewLine);
            this.xmlWriter.Write(stringBuilder.ToString());
        }

        public override void WriteLine(string message)
        {
            this.Write(message);
        }

        public override void WriteLine(string message, string category)
        {
            this.Write(message, category);
        }

        public override void Flush()
        {
            base.Flush();
            this.xmlWriter.Flush();
        }

        public override void Close()
        {
            base.Close();
            this.xmlWriter.Close();
        }

        protected override void Dispose(bool disposing)
        {
            if (!disposing)
                return;
            this.Flush();
            this.Close();
        }

        private string getPreambleMessage()
        {
            StringBuilder stringBuilder = new StringBuilder();
            StackTrace stackTrace = new StackTrace();
            int index1 = 0;
            var reflectedType = MethodBase.GetCurrentMethod().ReflectedType;
            if (reflectedType != null)
            {
                string str = reflectedType.ToString();
                MethodBase method;
                string fullName = null;
                do
                {
                    ++index1;
                    method = stackTrace.GetFrame(index1).GetMethod();
                    if (method.ReflectedType != null) fullName = method.ReflectedType.FullName;
                }
                while (fullName != null && (fullName.StartsWith("System") || fullName.EndsWith(str)));
                stringBuilder.Append("\t<DateTime>");
                stringBuilder.Append(DateTime.Now.ToString());
                stringBuilder.Append("</DateTime>");
                stringBuilder.Append(Environment.NewLine);
                stringBuilder.Append("\t<Class>");
                stringBuilder.Append(fullName);
                stringBuilder.Append("</Class>");
                stringBuilder.Append(Environment.NewLine);
                stringBuilder.Append("\t<Method>");
                stringBuilder.Append(method.Name);
                stringBuilder.Append("</Method>");
                stringBuilder.Append(Environment.NewLine);
                ParameterInfo[] parameters = method.GetParameters();
                foreach (ParameterInfo t in parameters)
                {
                    stringBuilder.Append("\t<Parameter type=\"");
                    stringBuilder.Append(t.ParameterType.Name);
                    stringBuilder.Append("\" name=\"");
                    stringBuilder.Append(t.Name);
                    stringBuilder.Append("\"/>");
                    stringBuilder.Append(Environment.NewLine);
                }
            }
            return stringBuilder.ToString();
        }
    }
}